home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / READ.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  31KB  |  1,247 lines

  1. /*    SCCS Id: @(#)read.c    3.0    89/11/15
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. #ifdef OVLB
  8.  
  9. boolean    known;
  10.  
  11. static const char NEARDATA readable[] = { '#', SCROLL_SYM,
  12. #ifdef SPELLS
  13.     SPBOOK_SYM,
  14. #endif
  15.     0 };
  16.  
  17. static void FDECL(explode, (struct obj *));
  18. static void NDECL(do_class_genocide);
  19. static void FDECL(stripspe,(struct obj *));
  20. static void FDECL(p_glow1,(struct obj *));
  21. static void FDECL(p_glow2,(struct obj *,const char *));
  22. static void FDECL(recharge,(struct obj *,int));
  23. static void FDECL(forget,(BOOLEAN_P));
  24.  
  25. #endif /* OVLB */
  26.  
  27. STATIC_DCL void FDECL(show_map_spot,(int,int));
  28.  
  29. #ifdef OVLB
  30.  
  31. int
  32. doread() {
  33.     register struct obj *scroll;
  34.     register boolean confused = (Confusion != 0);
  35.  
  36.     known = FALSE;
  37.     scroll = getobj(readable, "read");    /* "#-" added by GAN 10/22/86 */
  38.     if(!scroll) return(0);
  39.  
  40.     /* below added to allow reading of fortune cookies */
  41.     if(scroll->otyp == FORTUNE_COOKIE) {
  42.         if(flags.verbose)
  43.         You("break up the cookie and throw away the pieces.");
  44.         outrumor(bcsign(scroll), TRUE);
  45.         useup(scroll);
  46.         return(1);
  47.     } else
  48.         if(scroll->olet != SCROLL_SYM
  49. #ifdef SPELLS
  50.            && scroll->olet != SPBOOK_SYM
  51. #endif
  52.           ) {
  53.             pline("That is a silly thing to read.");
  54.             return(0);
  55.         }
  56.  
  57.     if(Blind)
  58. #ifdef SPELLS
  59.         if (scroll->olet == SPBOOK_SYM) {
  60.         pline("Being blind, you cannot read the mystic runes.");
  61.         return(0);
  62.         } else
  63. #endif
  64.         if (!scroll->dknown) {
  65.         pline("Being blind, you cannot read the formula on the scroll.");
  66.         return(0);
  67.         }
  68. #ifndef NO_SIGNAL
  69.     scroll->in_use = TRUE;        /* now being read */
  70. #endif
  71. #ifdef SPELLS
  72.     if(scroll->olet == SPBOOK_SYM) {
  73.         if(confused) {
  74.         You("cannot grasp the meaning of this tome.");
  75.         useup(scroll);
  76.         return(0);
  77.         } else
  78.         return(study_book(scroll));
  79.     }
  80. #endif
  81.     if(scroll->otyp != SCR_BLANK_PAPER) {
  82.       if(Blind)
  83.         pline("As you pronounce the formula on it, the scroll disappears.");
  84.       else
  85.         pline("As you read the scroll, it disappears.");
  86.       if(confused) {
  87.         if (Hallucination)
  88.         pline("Being so trippy, you screw up...");
  89.         else
  90.         pline("Being confused, you mispronounce the magic words...");
  91.       }
  92.     }
  93.     if(!seffects(scroll))  {
  94.         if(!objects[scroll->otyp].oc_name_known) {
  95.             if(known && !confused) {
  96.             makeknown(scroll->otyp);
  97.             more_experienced(0,10);
  98.             } else if(!objects[scroll->otyp].oc_uname)
  99.             docall(scroll);
  100.         }
  101.         if(!(scroll->otyp == SCR_BLANK_PAPER) || confused)
  102.             useup(scroll);
  103. #ifndef NO_SIGNAL
  104.         else scroll->in_use = FALSE;
  105. #endif
  106.     }
  107.     return(1);
  108. }
  109.  
  110. static void
  111. stripspe(obj)
  112. register struct obj *obj;
  113. {
  114.     if (obj->blessed) pline(nothing_happens);
  115.     else {
  116.         if (obj->spe > 0) {
  117.             obj->spe = 0;
  118.             Your("%s vibrates briefly.",xname(obj));
  119.         } else pline(nothing_happens);
  120.     }
  121. }
  122.  
  123. static void
  124. p_glow1(otmp)
  125. register struct obj    *otmp;
  126. {
  127.     Your("%s %s briefly.", xname(otmp),
  128.         Blind ? "vibrates" : "glows");
  129. }
  130.  
  131. static void
  132. p_glow2(otmp,color)
  133. register struct obj    *otmp;
  134. register const char *color;
  135. {
  136.     Your("%s %s%s for a moment.",
  137.         xname(otmp),
  138.         Blind ? "vibrates" : "glows ",
  139.         Blind ? (const char *)"" : Hallucination ? hcolor() : color);
  140. }
  141.  
  142. /*
  143.  * recharge an object; curse_bless is -1 if the recharging implement
  144.  * was cursed, +1 if blessed, 0 otherwise.
  145.  */
  146. static
  147. void
  148. recharge(obj, curse_bless)
  149. struct obj *obj;
  150. int curse_bless;
  151. {
  152.     register int n;
  153.     boolean is_cursed, is_blessed;
  154.  
  155.     is_cursed = curse_bless < 0;
  156.     is_blessed = curse_bless > 0;
  157.  
  158.     if (obj->olet != WAND_SYM) {
  159.         switch(obj->otyp) {
  160.         case MAGIC_MARKER:
  161.         if (is_cursed) stripspe(obj);
  162.         else if (obj->recharged) {
  163.             if (obj->spe < 3)
  164.             Your("marker seems permanently dried out.");
  165.             else
  166.             pline(nothing_happens);
  167.         }
  168.         else if (is_blessed) {
  169.             n = obj->spe;
  170.             if (n < 50) obj->spe = 50;
  171.             if (n >= 50 && n < 75) obj->spe = 75;
  172.             if (n >= 75) obj->spe += 10;
  173.             p_glow2(obj,blue);
  174.             obj->recharged = 1;
  175.         } else {
  176.             if (obj->spe < 50) obj->spe = 50;
  177.             else obj->spe++;
  178.             p_glow2(obj,white);
  179.             obj->recharged = 1;
  180.         }
  181.         break;
  182.         case LAMP:
  183.         if (is_cursed) stripspe(obj);
  184.         else if (is_blessed) {
  185.             n = rn2(11);
  186.             if (obj->spe < n) obj->spe = n;
  187.             else obj->spe += rnd(3);
  188.             p_glow2(obj,blue);
  189.         } else {
  190.             obj->spe++;
  191.             p_glow1(obj);
  192.         }
  193.         break;
  194.         case MAGIC_LAMP:
  195.         if (is_cursed) stripspe(obj);
  196.         else if (is_blessed > 0) {
  197.             if (obj->spe == 1 || obj->recharged)
  198.             pline(nothing_happens);
  199.             else {
  200.             obj->spe = 1;
  201.             obj->recharged = 1;
  202.             p_glow1(obj);
  203.             }
  204.         } else {
  205.             if (obj->spe == 1 || obj->recharged)
  206.             pline(nothing_happens);
  207.             else {
  208.             n = rn2(2);
  209.             if (!n) {
  210.                 obj->spe = 1;
  211.                 obj->recharged = 1;
  212.                 p_glow1(obj);
  213.             } else pline(nothing_happens);
  214.             }
  215.         }
  216.         break;
  217.         case CRYSTAL_BALL:
  218.         if (is_cursed) stripspe(obj);
  219.         else if (is_blessed) {
  220.             obj->spe = 6;
  221.             p_glow2(obj,blue);
  222.         } else {
  223.             if (obj->spe < 5) {
  224.             obj->spe++;
  225.             p_glow1(obj);
  226.             } else pline(nothing_happens);
  227.         }
  228.         break;
  229.         case BAG_OF_TRICKS:
  230.         if (is_cursed) stripspe(obj);
  231.         else if (is_blessed) {
  232.             if (obj->spe <= 10)
  233.             obj->spe += (5 + rnd(10));
  234.             else obj->spe += (5 + rnd(5));
  235.             p_glow2(obj,blue);
  236.         } else {
  237.             obj->spe += rnd(5);
  238.             p_glow1(obj);
  239.         }
  240.         break;
  241.         default:
  242.         You("have a feeling of loss.");
  243.         return;
  244.         } /* switch */
  245.     }
  246.     else {
  247.         if (obj->otyp == WAN_WISHING) {
  248.         if (obj->recharged) { /* recharged once already? */
  249.             explode(obj);
  250.             return;
  251.         }
  252.         if (is_cursed) stripspe(obj);
  253.         else if (is_blessed) {
  254.             if (obj->spe != 3) {
  255.             obj->spe = 3;
  256.             p_glow2(obj,blue);
  257.             } else {
  258.             explode(obj);
  259.             return;
  260.             }
  261.         } else {
  262.             if (obj->spe < 3) {
  263.             obj->spe++;
  264.             p_glow2(obj,blue);
  265.             } else pline(nothing_happens);
  266.         }
  267.         obj->recharged = 1; /* another recharging disallowed */
  268.         }
  269.         else {
  270.         if (is_cursed) stripspe(obj);
  271.         else if (is_blessed) {
  272.             if (objects[obj->otyp].bits & NODIR) {
  273.             n = rn1(5,11);
  274.             if (obj->spe < n) obj->spe = n;
  275.             else obj->spe++;
  276.             }
  277.             else {
  278.             n = rn1(5,4);
  279.             if (obj->spe < n) obj->spe = n;
  280.             else obj->spe++;
  281.             }
  282.             p_glow2(obj,blue);
  283.         } else {
  284.             obj->spe++;
  285.             p_glow1(obj);
  286.         }
  287.         }
  288.     }
  289. }
  290.  
  291. /*
  292.  * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch)
  293.  * controls the level of forgetfulness; 0 == part of the map, 1 == all of
  294.  * of map,  2 == part of map + spells, 3 == all of map + spells.
  295.  */
  296.  
  297. static
  298. void
  299. forget(howmuch)
  300. boolean howmuch;
  301. {
  302.     register int zx, zy;
  303.  
  304.     known = TRUE;
  305.     for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
  306.         if(howmuch & 1 || rn2(7))
  307.         if(!cansee(zx,zy))
  308.             levl[zx][zy].seen = levl[zx][zy].new =
  309.             levl[zx][zy].scrsym = 0;
  310.     docrt();
  311. #ifdef SPELLS
  312.     if(howmuch & 2) losespells();
  313. #endif
  314. }
  315.  
  316. int
  317. seffects(sobj)
  318. register struct obj    *sobj;
  319. {
  320.     register int cval = 0;
  321.     register boolean confused = (Confusion != 0);
  322.     register struct obj *otmp;
  323.  
  324.     switch(sobj->otyp) {
  325. #ifdef MAIL
  326.     case SCR_MAIL:
  327.         known = TRUE;
  328.         if (sobj->spe)
  329.             pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
  330.         /* note to the puzzled: the game Larn actually sends you junk
  331.          * mail if you win!
  332.          */
  333.         else readmail(/* scroll */);
  334.         break;
  335. #endif
  336.     case SCR_ENCHANT_ARMOR:
  337.         {
  338.         register schar s = 0;
  339.         otmp = some_armor();
  340.         if(!otmp) {
  341.             strange_feeling(sobj,
  342.                     !Blind ? "Your skin glows then fades." :
  343.                     "Your skin feels warm for a moment.");
  344.             return(1);
  345.         }
  346.         if(confused) {
  347.             if(Blind)
  348.                 Your("%s feels warm for a moment.",
  349.                 xname(otmp));
  350.             else
  351.                 Your("%s is covered by a %s %s %s!",
  352.                 xname(otmp),
  353.                 sobj->cursed ? "mottled" : "shimmering",
  354.                 Hallucination ? hcolor() :
  355.                   sobj->cursed ? black : (const char *)"gold",
  356.                 sobj->cursed ? "glow" :
  357.                   (is_shield(otmp) ? "layer" : "shield"));
  358.             if(!(sobj->cursed))
  359.                 otmp->rustfree = TRUE;
  360.             break;
  361.         }
  362. #ifdef TOLKIEN
  363.         if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  364. #else
  365.         if((otmp->spe > 3)
  366. #endif
  367.                 && rn2(otmp->spe) && !sobj->cursed) {
  368.         Your("%s violently %s%s for a while, then evaporates.",
  369.                 xname(otmp),
  370.                 Blind ? "vibrates" : "glows ",
  371.                 Blind ? nul : Hallucination ? hcolor() : silver);
  372.             if(is_cloak(otmp)) (void) Cloak_off();
  373.             if(is_boots(otmp)) (void) Boots_off();
  374.             if(is_helmet(otmp)) (void) Helmet_off();
  375.             if(is_gloves(otmp)) (void) Gloves_off();
  376.             if(is_shield(otmp)) (void) Shield_off();
  377.             if(otmp == uarm) (void) Armor_gone();
  378.             useup(otmp);
  379.             break;
  380.         }
  381.         s = sobj->blessed ? rnd(3) : sobj->cursed ? -1 : 1;
  382.         Your("%s %s%s for a %s.",
  383.             xname(otmp),
  384.             Blind ? "vibrates" : "glows ",
  385.             Blind ? nul : Hallucination ? hcolor() :
  386.               sobj->cursed ? black : silver,
  387.               (s*s>1) ? "while" : "moment");
  388.         otmp->cursed = sobj->cursed;
  389.         if (!otmp->blessed || sobj->cursed)
  390.             otmp->blessed = sobj->blessed;
  391.         otmp->spe += s;
  392.         adj_abon(otmp, s);
  393.         break;
  394.         }
  395.     case SCR_DESTROY_ARMOR:
  396.         {
  397.         otmp = some_armor();
  398.         if(confused) {
  399.             if(!otmp) {
  400.                 strange_feeling(sobj,"Your bones itch.");
  401.                 return(1);
  402.             }
  403.             otmp->rustfree = sobj->cursed;
  404.             p_glow2(otmp,purple);
  405.             break;
  406.         }
  407.         if(!sobj->cursed || (sobj->cursed && (!otmp || !otmp->cursed))) {
  408.             if(!destroy_arm(otmp)) {
  409.             strange_feeling(sobj,"Your skin itches.");
  410.             return(1);
  411.             }
  412.         } else {    /* armor and scroll both cursed */
  413.             Your("%s vibrates.", xname(otmp));
  414.             otmp->spe--;
  415.             make_stunned(HStun + rn1(10, 10), TRUE);
  416.         }
  417.         }
  418.         break;
  419.     case SCR_CONFUSE_MONSTER:
  420. #ifdef SPELLS
  421.     case SPE_CONFUSE_MONSTER:
  422. #endif
  423.         if(u.usym != S_HUMAN || sobj->cursed) {
  424.             if(!HConfusion) You("feel confused.");
  425.             make_confused(HConfusion + rnd(100),FALSE);
  426.         } else  if(confused) {
  427.             if(!sobj->blessed) {
  428.             Your("%s begin to %s%s.",
  429.                 makeplural(body_part(HAND)),
  430.                 Blind ? "tingle" : "glow ",
  431.                 Blind ? nul : Hallucination ? hcolor() : purple);
  432.             make_confused(HConfusion + rnd(100),FALSE);
  433.             } else {
  434.             pline("A %s%s surrounds your %s.",
  435.                 Blind ? nul : Hallucination ? hcolor() : red,
  436.                 Blind ? "faint buzz" : " glow",
  437.                 body_part(HEAD));
  438.             make_confused(0L,TRUE);
  439.             }
  440.         } else {
  441.             if (!sobj->blessed) {
  442.             Your("%s%s %s%s.",
  443.             makeplural(body_part(HAND)),
  444.             Blind ? "" : " begin to glow",
  445.             Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red,
  446.             u.umconf ? " even more" : "");
  447.             u.umconf++;
  448.             } else {
  449.             if (Blind)
  450.                 Your("%s tingle %s sharply.",
  451.                 makeplural(body_part(HAND)),
  452.                 u.umconf ? "even more" : "very");
  453.             else
  454.                 Your("%s glow a%s brilliant %s.",
  455.                 makeplural(body_part(HAND)),
  456.                 u.umconf ? "n even more" : "",
  457.                 Hallucination ? hcolor() : red);
  458.             u.umconf += (1 + rnd(8));
  459.             }
  460.         }
  461.         break;
  462.     case SCR_SCARE_MONSTER:
  463. #ifdef SPELLS
  464.     case SPE_CAUSE_FEAR:
  465. #endif
  466.         {    register int ct = 0;
  467.         register struct monst *mtmp;
  468.  
  469.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  470.             if(cansee(mtmp->mx,mtmp->my)) {
  471.             if(confused || sobj->cursed) {
  472.                 mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0;
  473.                 mtmp->mcanmove = 1;
  474.             } else
  475.                 if (! resist(mtmp, sobj->olet, 0, NOTELL))
  476.                 mtmp->mflee = 1;
  477.             if(!mtmp->mtame) ct++;    /* pets don't laugh at you */
  478.             }
  479.         if(!ct)
  480.               You("hear %s in the distance.",
  481.                    (confused || sobj->cursed) ? "sad wailing" :
  482.                             "maniacal laughter");
  483.         else
  484. #ifdef SPELLS
  485.              if(sobj->otyp == SCR_SCARE_MONSTER)
  486. #endif
  487.                 You("hear %s close by.",
  488.                   (confused || sobj->cursed) ? "sad wailing" :
  489.                          "maniacal laughter");
  490.         break;
  491.         }
  492.     case SCR_BLANK_PAPER:
  493.         if(confused)
  494.             You("try to read the strange patterns on this scroll, but it disappears.");
  495.         else  {
  496.             pline("This scroll seems to be blank.");
  497.             known = TRUE;
  498.         }
  499.         break;
  500.     case SCR_REMOVE_CURSE:
  501. #ifdef SPELLS
  502.     case SPE_REMOVE_CURSE:
  503. #endif
  504.         {    register struct obj *obj;
  505.         if(confused)
  506.             if (Hallucination)
  507.             You("feel the power of the Force against you!");
  508.             else
  509.             You("feel like you need some help.");
  510.         else
  511.             if (Hallucination)
  512.             You("feel in touch with the Universal Oneness.");
  513.             else
  514.             You("feel like someone is helping you.");
  515.  
  516.         if(sobj->cursed) pline("The scroll disintegrates.");
  517.         else {
  518.             for(obj = invent; obj ; obj = obj->nobj)
  519.             if(sobj->blessed || obj->owornmask ||
  520.                (obj->otyp == LOADSTONE)) {
  521.                 if(confused) blessorcurse(obj, 2);
  522.                 else obj->cursed = 0;
  523.             }
  524.         }
  525.         if(Punished && !confused) unpunish();
  526.         break;
  527.         }
  528.     case SCR_CREATE_MONSTER:
  529. #if defined(WIZARD) || defined(EXPLORE_MODE)
  530.         if (wizard || discover)
  531.         known = TRUE;
  532. #endif /* WIZARD || EXPLORE_MODE */
  533. #ifdef SPELLS
  534.     case SPE_CREATE_MONSTER:
  535. #endif
  536.         {    register int cnt = 1;
  537.  
  538.         if(!rn2(73)) cnt += rnd(4);
  539.         if(confused || sobj->cursed) cnt += 12;
  540.         while(cnt--) {
  541. #if defined(WIZARD) || defined(EXPLORE_MODE)
  542.             if((!wizard && !discover) || !create_particular())
  543. #endif /* WIZARD || EXPLORE_MODE */
  544.             (void) makemon (confused ? &mons[PM_ACID_BLOB] :
  545.                     (struct permonst *) 0, u.ux, u.uy);
  546.         }
  547.         break;
  548.         }
  549. /*        break;    /*NOTREACHED*/
  550.     case SCR_ENCHANT_WEAPON:
  551.         if(uwep && (uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE
  552.             || uwep->otyp == UNICORN_HORN) && confused) {
  553.         /* olet check added 10/25/86 GAN */
  554.                         uwep->rustfree = !(sobj->cursed);
  555.             if(Blind)
  556.                 Your("weapon feels warm for a moment.");
  557.             else
  558.                 Your("%s covered by a %s %s %s!",
  559.                 aobjnam(uwep, "are"),
  560.                 sobj->cursed ? "mottled" : "shimmering",
  561.                 Hallucination ? hcolor() :
  562.                   sobj->cursed ? purple : (const char *)"gold",
  563.                 sobj->cursed ? "glow" : "shield");
  564.         } else return !chwepon(sobj, bcsign(sobj)*2+1);
  565.         break;
  566.     case SCR_TAMING:
  567. #ifdef SPELLS
  568.     case SPE_CHARM_MONSTER:
  569. #endif
  570.         {    register int i,j;
  571.         register int bd = confused ? 5 : 1;
  572.         register struct monst *mtmp;
  573.  
  574.         for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
  575.         if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) {
  576.             if(sobj->cursed) {
  577.             if(!mtmp->mtame) mtmp->mpeaceful = 0;
  578.             } else {
  579.             if (mtmp->isshk) {
  580.                 if (!mtmp->mpeaceful) {
  581.                 kludge("%s calms down.", Monnam(mtmp));
  582.                 mtmp->mpeaceful = 1;
  583.                 }
  584.             } else if(!resist(mtmp, sobj->olet, 0, NOTELL))
  585.                 (void) tamedog(mtmp, (struct obj *) 0);
  586.             }
  587.         }
  588.         break;
  589.         }
  590.     case SCR_GENOCIDE:
  591.         You("have found a scroll of genocide!");
  592. #ifdef SPELLS
  593.     case SPE_GENOCIDE:
  594. #endif
  595.         known = TRUE;
  596.         if (sobj->blessed) do_class_genocide();
  597.         else do_genocide(!sobj->cursed | (2 * !!Confusion));
  598.         break;
  599.     case SCR_LIGHT:
  600.         if(!Blind) known = TRUE;
  601.         litroom(!confused && !sobj->cursed);
  602.         break;
  603.     case SCR_TELEPORTATION:
  604.         if(confused || sobj->cursed) level_tele();
  605.         else {
  606.             register int uroom = inroom(u.ux, u.uy);
  607.  
  608.             if (sobj->blessed && !Teleport_control) {
  609.                 known = TRUE;
  610. #ifndef MACOS
  611.                 pline("Do you wish to teleport? ");
  612.                 if (yn()=='n') break;
  613. #else
  614.                 if(!flags.silent) SysBeep(1);
  615.                 if(UseMacAlertText(128, "Do you wish to teleport ?") == 2)
  616.                     break;
  617. #endif
  618.             }
  619.             tele();
  620.             if(uroom != inroom(u.ux, u.uy)) known = TRUE;
  621.             if(Teleport_control) known = TRUE;
  622.         }
  623.         break;
  624.     case SCR_GOLD_DETECTION:
  625.         if (confused || sobj->cursed) return(trap_detect(sobj));
  626.         else return(gold_detect(sobj));
  627.     case SCR_FOOD_DETECTION:
  628. #ifdef SPELLS
  629.     case SPE_DETECT_FOOD:
  630. #endif
  631.         if (food_detect(sobj))
  632.             return(1);    /* nothing detected */
  633.         break;
  634. #ifdef SPELLS
  635.     case SPE_IDENTIFY:
  636.         cval = rn2(5);
  637.         goto id;
  638. #endif
  639.     case SCR_IDENTIFY:
  640.         /* known = TRUE; */
  641.         if(confused)
  642.             You("identify this as an identify scroll.");
  643.         else
  644.             pline("This is an identify scroll.");
  645.         if (sobj->blessed || (!sobj->cursed && !rn2(5)))
  646.             cval = rn2(5);
  647.             /* Note: if rn2(5)==0, identify all items */
  648.         else    cval = 1;
  649.         useup(sobj);
  650.         makeknown(SCR_IDENTIFY);
  651. #ifdef SPELLS
  652.     id:
  653. #endif
  654.         if(!confused)
  655.             while(invent && !ggetobj("identify", identify, cval));
  656.         return(1);
  657.     case SCR_CHARGING:
  658.         if (confused) {
  659.             You("feel charged up!");
  660. #ifdef SPELLS
  661.             if (u.uen < u.uenmax)
  662.             u.uen = u.uenmax;
  663.             else
  664.             u.uen = u.uenmax + d(5,4);
  665.             flags.botl = 1;
  666. #endif
  667.             break;
  668.         }
  669.         known = TRUE;
  670.         pline("This is a charging scroll.");
  671.         otmp = getobj("0#", "charge");
  672.         if (!otmp) break;
  673.         recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
  674.         break;
  675.     case SCR_MAGIC_MAPPING:
  676.         known = TRUE;
  677.         pline("On this scroll %s a map.", confused ? "was" : "is");
  678. #ifdef SPELLS
  679.     case SPE_MAGIC_MAPPING:
  680. #endif
  681.         cval = (sobj->cursed && !confused);
  682.         if(cval) HConfusion = 1;    /* to screw up map */
  683.         do_mapping();
  684.         if(cval) {
  685.             HConfusion = 0;        /* restore */
  686.             pline("Unfortunately, it is of a very poor quality.");
  687.         }
  688.         break;
  689.     case SCR_AMNESIA:
  690.         known = TRUE;
  691.         forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) );
  692.         if (Hallucination) /* Ommmmmm! */
  693.             Your("mind releases itself from mundane concerns.");
  694.         else if (!strncmp(plname, "Maud", 4))
  695.             pline("As your mind turns inward on itself, you forget everything else.");
  696.         else if (rn2(2))
  697.             pline("Who was that Maud person anyway?");
  698.         else
  699.             pline("Thinking of Maud you forget everything else.");
  700.         break;
  701.     case SCR_FIRE:
  702.         {    register int num;
  703.         register struct monst *mtmp;
  704. /*
  705.  * Note: Modifications have been made as of 3.0 to allow for some damage
  706.  *     under all potential cases.
  707.  */
  708.         cval = bcsign(sobj);
  709.         useup(sobj);
  710.         makeknown(SCR_FIRE);
  711.         if(confused) {
  712.             if(Fire_resistance) {
  713.               shieldeff(u.ux, u.uy);
  714.             if(!Blind)
  715.                 pline("Oh, look, what a pretty fire in your %s.",
  716.                 makeplural(body_part(HAND)));
  717.             else You("feal a pleasant warmth in your %s.",
  718.                 makeplural(body_part(HAND)));
  719.             } else {
  720.             pline("The scroll catches fire and you burn your %s.",
  721.                 makeplural(body_part(HAND)));
  722.             losehp(1, "scroll of fire", KILLED_BY_AN);
  723.             }
  724.             return(1);
  725.         }
  726.         pline("The scroll erupts in a tower of flame!");
  727.         num = rnd(6) - 3 * cval;
  728.         if(num <= 0 || Fire_resistance) {
  729.             shieldeff(u.ux, u.uy);
  730.             You("are uninjured.");
  731.         } else {
  732.             u.uhpmax -= num;
  733.             losehp(num, "scroll of fire", KILLED_BY_AN);
  734.         }
  735.         destroy_item(SCROLL_SYM, AD_FIRE);
  736. #ifdef SPELLS
  737.         destroy_item(SPBOOK_SYM, AD_FIRE);
  738. #endif
  739.         destroy_item(POTION_SYM, AD_FIRE);
  740.  
  741.         num = (2*(rn1(3, 3) + 2 * cval) + 1)/3;
  742.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  743.             if(dist(mtmp->mx,mtmp->my) < 3) {
  744.             if (resists_fire(mtmp->data)) continue;
  745.             if (u.uswallow) {
  746.                 if (mtmp != u.ustuck) continue;
  747.                 if (is_animal(u.ustuck->data))
  748.                     pline("%s gets heartburn.", 
  749.                           Monnam(u.ustuck));
  750.                 else
  751.                     You("toast %s slightly.", 
  752.                         Monnam(u.ustuck)); 
  753.                 num *= 2;
  754.             }
  755.             mtmp->mhp -= num;        /* No saving throw! */
  756.             if(resists_cold(mtmp->data))
  757.                 mtmp->mhp -= 3*num;
  758.             if(mtmp->mhp < 1) {
  759.                 killed(mtmp);
  760.                 break;        /* primitive */
  761.             }
  762.             }
  763.         }
  764.         return(1);
  765.         }
  766.     case SCR_PUNISHMENT:
  767.         known = TRUE;
  768.         if(confused || sobj->blessed) {
  769.             You("feel guilty.");
  770.             break;
  771.         }
  772.         punish(sobj);
  773.         break;
  774.     default:
  775.         impossible("What weird effect is this? (%u)", sobj->otyp);
  776.     }
  777.     return(0);
  778. }
  779.  
  780. static void
  781. explode(obj)
  782. register struct obj *obj;
  783. {
  784.     Your("%s vibrates violently, and explodes!",xname(obj));
  785.     bell();
  786.     losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN);
  787.     useup(obj);
  788. }
  789.  
  790. void
  791. litroom(on)
  792. register boolean on;
  793. {
  794.     register int zx,zy;
  795.  
  796.     /* first produce the text (provided he is not blind) */
  797.     if(Blind) goto do_it;
  798.     if(!on) {
  799.         if(u.uswallow || is_maze_lev || levl[u.ux][u.uy].typ == CORR ||
  800.             !levl[u.ux][u.uy].lit) {
  801.             pline("It seems even darker in here than before.");
  802.             return;
  803.         } else
  804.             pline("It suddenly becomes dark in here.");
  805.     } else {
  806.         if(u.uswallow){
  807.             if (is_animal(u.ustuck->data))
  808.                 pline("%s's stomach is lit.", Monnam(u.ustuck));
  809.             else
  810.                 if (is_whirly(u.ustuck->data))
  811.                     pline("%s shines briefly.", 
  812.                           Monnam(u.ustuck));
  813.                 else
  814.                     pline("%s glistens.", Monnam(u.ustuck));
  815.             return;
  816.         }
  817.         if(is_maze_lev){
  818.             pline(nothing_happens);
  819.             return;
  820.         }
  821.         if(levl[u.ux][u.uy].typ == CORR) {
  822.             pline("The corridor lights up around you, then fades.");
  823.             return;
  824.         } else if(levl[u.ux][u.uy].lit) {
  825.             pline("The light here seems better now.");
  826.             return;
  827.         } else
  828.             pline("The room is lit.");
  829.     }
  830.  
  831. do_it:
  832.     if(levl[u.ux][u.uy].lit == on)
  833.         return;
  834.     if (inroom(u.ux,u.uy) < 0)
  835.         return;
  836.     getcorners(&seelx,&seehx,&seely,&seehy,&seelx2,&seehx2,&seely2,&seehy2);
  837.  
  838.     for(zy = seely; zy <= seehy; zy++)
  839.         for(zx = seelx; zx <= seehx; zx++) {
  840.             levl[zx][zy].lit = on;
  841.             if(!Blind && dist(zx,zy) > 2)
  842.                 if(on) prl(zx,zy); else nosee(zx,zy);
  843.         }
  844.     for(zy = seely2; zy <= seehy2; zy++)
  845.         for(zx = seelx2; zx <= seehx2; zx++) {
  846.             levl[zx][zy].lit = on;
  847.             if(!Blind && dist(zx,zy) > 2)
  848.                 if(on) prl(zx,zy); else nosee(zx,zy);
  849.         }
  850.     if(!on) seehx = 0;
  851. }
  852.  
  853. static void
  854. do_class_genocide()
  855. {
  856.     register int i, j, immunecnt, gonecnt, goodcnt;
  857.     char buf[BUFSZ];
  858.  
  859.     for(j=0; ; j++) {
  860.         if (j >= 5) {
  861.             pline(thats_enough_tries);
  862.             return;
  863.         }
  864.         do {
  865.     pline("What class of monsters do you wish to genocide? [type a letter] ");
  866.             getlin(buf);
  867.         } while (buf[0]=='\033' || strlen(buf) != 1);
  868.         immunecnt = gonecnt = goodcnt = 0;
  869.         for(i=0; mons[i].mlet; i++) {
  870.             if(mons[i].mlet == buf[0]) {
  871.                 if (!(mons[i].geno & G_GENO)) immunecnt++;
  872.                 else if(mons[i].geno & G_GENOD) gonecnt++;
  873.                 else goodcnt++;
  874.             }
  875.         }
  876.         if (!goodcnt && buf[0] != S_HUMAN) {
  877.             if (gonecnt)
  878.     pline("All such monsters are already nonexistent.");
  879.             else if (immunecnt)
  880.     You("aren't permitted to genocide such monsters.");
  881.             else
  882.     pline("That symbol does not represent any monster.");
  883.             continue;
  884.         }
  885.         for(i=0; mons[i].mlet; i++) {
  886.             if(mons[i].mlet == buf[0]) {
  887.             register struct monst *mtmp, *mtmp2;
  888.             char *n = makeplural(mons[i].mname);
  889.  
  890.             if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO)
  891.                 && !(mons[i].geno & G_GENOD))) {
  892.             /* This check must be first since player monsters might
  893.              * have G_GENOD or !G_GENO.
  894.              */
  895.                 pline("Wiped out all %s.", n);
  896.                 if (&mons[i] == player_mon()) {
  897.                 u.uhp = -1;
  898.                 killer_format = KILLED_BY_AN;
  899.                 killer = "scroll of genocide";
  900. #ifdef POLYSELF
  901.                 if (u.umonnum >= 0)
  902.                     You("feel dead inside.");
  903.                 else
  904. #endif
  905.                     done(GENOCIDED);
  906.                 }
  907.                 /* for simplicity (and fairness) let's avoid
  908.                  * alignment changes here...
  909.                  */
  910. #ifdef POLYSELF
  911.                 if (i==u.umonnum) rehumanize();
  912. #endif
  913.                 mons[i].geno |= G_GENOD;
  914.                 for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  915.                 mtmp2 = mtmp->nmon;
  916.                 if(mtmp->data == &mons[i])
  917.                     mondead(mtmp);
  918.                 }
  919.             } else if ((mons[i].geno & G_GENOD) &&
  920.               !(mons[i].geno & G_UNIQ))
  921.                 pline("All %s are already nonexistent.", n);
  922.             else
  923.                 You("aren't permitted to genocide %s%s.",
  924.                 i == PM_WIZARD_OF_YENDOR ? "the " : "",
  925.                 type_is_pname(&mons[i]) ? mons[i].mname : n);
  926.             }
  927.         }
  928.         return;
  929.     }
  930. }
  931.         
  932. #define REALLY 1
  933. #define PLAYER 2
  934. void
  935. do_genocide(how)
  936. int how;
  937. /* 0 = no genocide; create monsters (cursed scroll) */
  938. /* 1 = normal genocide */
  939. /* 3 = forced genocide of player */
  940. {
  941.     char buf[BUFSZ];
  942.     register int    i, j, killplayer = 0;
  943.     register struct permonst *ptr;
  944.     register struct monst *mtmp, *mtmp2;
  945.  
  946.     if (how & PLAYER) {
  947.         ptr = player_mon();
  948.         Strcpy(buf, ptr->mname);
  949.         killplayer++;
  950.     } else {
  951.         for(j = 0; ; j++) {
  952.         if(j >= 5) {
  953.             pline(thats_enough_tries);
  954.             return;
  955.         }
  956.         pline("What monster do you want to genocide? [type the name] ");
  957.         getlin(buf);
  958.  
  959.         if(strlen(buf) && (!strncmp(buf, pl_character, PL_CSIZ))) {
  960.     /* Note: pl_character starts with capitals and player_mon does not */
  961.             ptr = player_mon();
  962.             killplayer++;
  963.             goto deadmeat;
  964.         } else {
  965.             i = name_to_mon(buf);
  966.             if(i == -1 || (mons[i].geno & G_GENOD)) {
  967.             pline("Such creatures do not exist in this world.");
  968.             continue;
  969.             }
  970.             ptr = &mons[i];
  971.             if (ptr == player_mon()) {
  972.             killplayer++;
  973.             goto deadmeat;
  974.             }
  975.             if (is_human(ptr)) adjalign(-sgn(u.ualigntyp));
  976.             if (is_demon(ptr)) adjalign(sgn(u.ualigntyp));
  977.  
  978.             if(!(ptr->geno & G_GENO))  {
  979.             if(flags.soundok) {
  980.                 if(flags.verbose)
  981.             pline("A thunderous voice booms though the caverns:");
  982.                 pline("\"No, mortal!  That will not be done.\"");
  983.             }
  984.             continue;
  985.             }
  986.             break;
  987.         }
  988.         }
  989.     }
  990. deadmeat:
  991.     if (Hallucination) {
  992. #ifdef POLYSELF
  993.         if (u.umonnum != -1)
  994.         Strcpy(buf,uasmon->mname);
  995.         else
  996. #endif
  997.         {
  998.         Strcpy(buf, pl_character);
  999.         buf[0] += 'a' - 'A';
  1000.         }
  1001.     } else Strcpy(buf,ptr->mname); /* make sure we have standard singular */
  1002.     if (how & REALLY) {
  1003.         pline("Wiped out all %s.", makeplural(buf));
  1004.         if(killplayer) {
  1005.         u.uhp = -1;
  1006.         killer_format = KILLED_BY_AN;
  1007.         killer = "genocide spell";
  1008. #ifdef POLYSELF
  1009.     /* A polymorphed character will die as soon as he is rehumanized. */
  1010.         if(u.umonnum >= 0)    You("feel dead inside.");
  1011.         else
  1012. #endif
  1013.             done(GENOCIDED);
  1014.         return;
  1015.         }
  1016. #ifdef POLYSELF
  1017.         else if (ptr == uasmon) rehumanize();
  1018. #endif
  1019.         ptr->geno |= G_GENOD;
  1020.         for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1021.         mtmp2 = mtmp->nmon;
  1022.         if(mtmp->data == ptr)
  1023.             mondead(mtmp);
  1024.         }
  1025.     } else {
  1026.         pline("Sent in some %s.", makeplural(buf));
  1027.         j = rnd(3) + 3;
  1028.         for(i=1; i<=j; i++) {
  1029.         struct monst *mmon = makemon(ptr, u.ux, u.uy);
  1030.         struct obj *otmp;
  1031.  
  1032.         while(otmp = (mmon->minvent)) {
  1033.             mmon->minvent = otmp->nobj;
  1034.             free((genericptr_t)otmp);
  1035.         }
  1036.         }
  1037.     }
  1038. }
  1039.  
  1040. #endif /* OVLB */
  1041. #ifdef OVL0
  1042.  
  1043. STATIC_OVL void
  1044. show_map_spot(x, y)
  1045. register int x, y;
  1046. {
  1047.     register struct rm *lev;
  1048.     register int num;
  1049.  
  1050.     if((Confusion != 0) && rn2(7)) return;
  1051.     lev = &(levl[x][y]);
  1052.     if((num = lev->typ) == 0) return;
  1053.  
  1054.     if(num == SCORR) {
  1055.         lev->typ = CORR;
  1056.         lev->scrsym = CORR_SYM;
  1057.     /*
  1058.      * magic mapping shouldn't find secret doors,
  1059.      * especially on the stronghold level
  1060.      */
  1061.     } else if(lev->seen) return;
  1062.     if(num != ROOM)
  1063.     {
  1064.         lev->seen = lev->new = 1;
  1065.         if(lev->scrsym == STONE_SYM || !lev->scrsym)
  1066.             newsym(x, y);
  1067.         else    on_scr(x, y);
  1068.     }
  1069. }
  1070.  
  1071. void
  1072. do_mapping() {
  1073.     register int zx, zy;
  1074.  
  1075.     for(zy = 0; zy < ROWNO; zy++)
  1076.         for(zx = 0; zx < COLNO; zx++)
  1077.         show_map_spot(zx, zy);
  1078. }
  1079.  
  1080. #endif /* OVL0 */
  1081. #ifdef OVLB
  1082.  
  1083. void
  1084. do_vicinity_map() {
  1085.     register int zx, zy;
  1086.     
  1087.     for(zy = (u.uy-5 < 0 ? 0 : u.uy-5); 
  1088.             zy < (u.uy+6 > ROWNO ? ROWNO : u.uy+6); zy++)
  1089.         for(zx = (u.ux-9 < 0 ? 0 : u.ux-9); 
  1090.             zx < (u.ux+10 > COLNO ? COLNO : u.ux+10); zx++)
  1091.         show_map_spot(zx, zy);
  1092. }
  1093.  
  1094. int
  1095. gold_detect(sobj)
  1096. register struct obj    *sobj;
  1097. {
  1098.     register struct gold *gtmp;
  1099.  
  1100.     if(!fgold) {
  1101.         if(sobj)
  1102.             strange_feeling(sobj, "You feel materially poor.");
  1103.         return(1);
  1104.     } else {
  1105.         known = TRUE;
  1106.         for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
  1107.             if(gtmp->gx != u.ux || gtmp->gy != u.uy)
  1108.                 goto outgoldmap;
  1109.         /* only under me - no separate display required */
  1110.         You("notice some gold between your %s.",
  1111.             makeplural(body_part(FOOT)));
  1112.         return(0);
  1113.     outgoldmap:
  1114.         cls();
  1115.         for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
  1116.             at( gtmp->gx, gtmp->gy,
  1117.             (uchar)(Hallucination ? rndobjsym() : GOLD_SYM),
  1118.             AT_OBJ);
  1119.         prme();
  1120.         You("feel very greedy, and sense gold!");
  1121.         more();
  1122.         docrt();
  1123.     }
  1124.     return(0);
  1125. }
  1126.  
  1127. /* food_detection is pulled out so that it     */
  1128. /* can also be used in the crystal ball routine    */
  1129. /* returns 1 if nothing was detected        */
  1130. /* returns 0 if something was detected        */
  1131. int
  1132. food_detect(sobj)
  1133. register struct obj    *sobj;
  1134. {
  1135.     register boolean confused = (Confusion || (sobj && sobj->cursed));
  1136.     register int ct = 0, ctu = 0;
  1137.     register struct obj *obj;
  1138.     register char foodsym = confused ? POTION_SYM : FOOD_SYM;
  1139.  
  1140.     for(obj = fobj; obj; obj = obj->nobj)
  1141.         if(obj->olet == foodsym) {
  1142.             if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
  1143.             else ct++;
  1144.         }
  1145.     if(!ct && !ctu) {
  1146.         if (sobj) strange_feeling(sobj,"Your nose twitches.");
  1147.         return(1);
  1148.     } else if(!ct) {
  1149.         known = TRUE;
  1150.         You("%s %s nearby.", sobj ? "smell" : "sense",
  1151.             confused ? "something" : "food");
  1152.     } else {
  1153.         known = TRUE;
  1154.         cls();
  1155.         for(obj = fobj; obj; obj = obj->nobj)
  1156.             if(obj->olet == foodsym)
  1157.             at(obj->ox, obj->oy,
  1158.                (uchar)(Hallucination ? rndobjsym() : FOOD_SYM),
  1159.                AT_OBJ);
  1160.         prme();
  1161.         if (sobj) Your("nose tingles and you smell %s.",
  1162.                 confused ? "something" : "food");
  1163.         else You("sense %s.", confused ? "something" : "food");
  1164.         more();
  1165.         docrt();
  1166.     }
  1167.     return(0);
  1168. }
  1169.  
  1170. void
  1171. punish(sobj)
  1172. register struct obj    *sobj;
  1173. {
  1174.     You("are being punished for your misbehavior!");
  1175.     if(Punished){
  1176.         Your("iron ball gets heavier.");
  1177.         uball->owt += 15 * (1 + sobj->cursed);
  1178.         return;
  1179.     }
  1180.     setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy, TRUE), W_CHAIN);
  1181.     setworn(mkobj_at(BALL_SYM, u.ux, u.uy, TRUE), W_BALL);
  1182.     uball->spe = 1;        /* special ball (see save) */
  1183. }
  1184.  
  1185. void
  1186. unpunish()
  1187. {        /* remove the ball and chain */
  1188.     freeobj(uchain);
  1189.     unpobj(uchain);
  1190.     free((genericptr_t) uchain);
  1191.     setworn((struct obj *)0, W_CHAIN);
  1192.     uball->spe = 0;
  1193.     setworn((struct obj *)0, W_BALL);
  1194. }
  1195.  
  1196. /* some creatures have special data structures that only make sense in their
  1197.  * normal locations -- if the player tries to create one elsewhere, or to revive
  1198.  * one, the disoriented creature becomes a zombie
  1199.  */
  1200. boolean
  1201. cant_create(mtype)
  1202. int *mtype;
  1203. {
  1204.  
  1205.     if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER
  1206. #if defined(ALTARS) && defined(THEOLOGY)
  1207.          || *mtype==PM_TEMPLE_PRIEST || *mtype==PM_TEMPLE_PRIESTESS
  1208. #endif
  1209.                                 ) {
  1210.         *mtype = PM_HUMAN_ZOMBIE;
  1211.         return TRUE;
  1212.     } else
  1213.         return FALSE;
  1214. }
  1215.  
  1216. #if defined(WIZARD) || defined(EXPLORE_MODE)
  1217. boolean
  1218. create_particular()
  1219. {
  1220.     char buf[BUFSZ];
  1221.     int which, tries = 0;
  1222.  
  1223.     do {
  1224.         pline("Create what kind of monster? [type the name] ");
  1225.         getlin(buf);
  1226.         which = name_to_mon(buf);
  1227.         if (which < 0) pline("I've never heard of such monsters.");
  1228.         else break;
  1229.     } while (++tries < 5);
  1230.     if (tries == 5) pline(thats_enough_tries);
  1231.     else {
  1232.         if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&
  1233.                                 !Blind) {
  1234.         if (mons[which].geno & G_GENOD)
  1235. pline("An image of the creature forms, wavers momentarily, then fades.");
  1236.         else
  1237. pline("The disoriented creature's eyes slowly glaze over.");
  1238.         }
  1239.         (void) makemon(&mons[which], u.ux, u.uy);
  1240.         return TRUE;
  1241.     }
  1242.     return FALSE;
  1243. }
  1244. #endif /* WIZARD || EXPLORE_MODE */
  1245.  
  1246. #endif /* OVLB */
  1247.